package chapter8;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author caiya
 * @date 2020/4/6 21:12
 * @description
 */
public class ThreadFactoryTest {
    /**
     * 简单定义一个线程工厂，提供给线程池使用
     * @param args
     */
    static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 60L,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("ASYNC-TEST-POOL") , new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        threadPoolExecutor.execute(() -> {
            throw new NullPointerException();
        });
        Future<String> stringFuture = threadPoolExecutor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "hello world!";
            }
        });
        System.out.println(stringFuture.get());
        threadPoolExecutor.shutdown();
    }

    /**
     * 自定义线程工厂
     */
    static class NamedThreadFactory implements ThreadFactory{
        // 线程池的编号
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        // 线程编号
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        // 线程前缀
        private final String namePrefix;

        NamedThreadFactory(String name) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                    Thread.currentThread().getThreadGroup();

            if (name == null || name.isEmpty()) {
                name = "pool-";
            }

            namePrefix = name +
                    poolNumber.getAndIncrement() +
                    "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r,
                    namePrefix + threadNumber.getAndIncrement(),
                    0);
            if (t.isDaemon()) {
                t.setDaemon(false);
            }
            if (t.getPriority() != Thread.NORM_PRIORITY) {
                t.setPriority(Thread.NORM_PRIORITY);
            }
            return t;
        }
    }
}
